Zaboha proc ??? - Dynamicke pole a BlockRead ^

Otázka od: David Kraina

14. 11. 2002 19:23

Nazdar,
 zaboha nemuzu prijit na to, proc to nefunguje a vyhazuje hlasku
Access Volation. Chci proste nacist cely soubor do pameti do pole,
ktere se prizpusobi velikosti pole. Neni to tim, ze by nestacila
pamet, ten soubor ma 40kB...
Zkousel jsem ruzne jako napriklad FileSize(INF)-1, v BlockRead misto
SizeOf(B1) na FileSize(INF), a jiné, ale stejný výsledek. Když jsem
B1 přetypoval na pevné pole, tak to jede. Mam D6.

Var B1:Array of Char;
    INF:File Of Char;
    I:LongInt;
Begin
 AssignFile(INF,'C:\E1.EXE');
 {$I-}
 Reset(INF);
 {$I+}
 If IOResult<>0 Then
  Application.MessageBox(PChar('Error1'),PChar(''))
 Else Begin
  SetLength(B1,FileSize(INF));
  BlockRead(INF,B1,SizeOf(B1),I);
  CloseFile(INF);
 End;
...
End;

______________________________________________________________________
Reklama:
Poctenicko pro kazdy den: http://www.novinky.cz

Odpovedá: David Kraina

14. 11. 2002 20:57

Tak to sice mozna jo, ale neni to resenim, protoze je to strasne
pomale. Testovaci soubor mel sice 40kB, ale musi to fungovat i pro
40MB a nez to po tom jednom znaku donacita, u pocitace usnu. Prave
proto to ctu po blocich, tentokrate to musi byt blok celeho souboru,
jelikoz ten text budu pomoci komprese zkracovat... DKx.


> Takto by to mohlo fungovat  
>
> Robo CAW
>
> Var B1:Array of Char;
> INF:File Of Char;
> j, I:LongInt;
> Begin
> AssignFile(INF,'C:\p.txt');
> {$I-}
> Reset(INF);
> {$I+}
> If IOResult<>0 Then
> Application.MessageBox(PChar('Error1'),PChar(''))
> Else Begin
> SetLength(B1,FileSize(INF)+1);
> j:= 0;
> while not eof(inf) do
> begin
> Read(inf, b1[j]);
> Inc(j);
> end;
> CloseFile(INF);
> End;
> End;


______________________________________________________________________
Reklama:
DUMPINGOVÉ CENY ve všech obchodech Internet Mall!
http://www.mall.cz - ověřte si to!

Odpovedá: Robert Suska

14. 11. 2002 20:20

Ahoj!

Takto by to mohlo fungovat  

Robo CAW

Var B1:Array of Char;
    INF:File Of Char;
    j, I:LongInt;
Begin
 AssignFile(INF,'C:\p.txt');
 {$I-}
 Reset(INF);
 {$I+}
 If IOResult<>0 Then
  Application.MessageBox(PChar('Error1'),PChar(''))
 Else Begin
 SetLength(B1,FileSize(INF)+1);
 j:= 0;
 while not eof(inf) do
  begin
   Read(inf, b1[j]);
   Inc(j);
  end;
 CloseFile(INF);
 End;
End;


----- Original Message -----
From: "David Kraina" <DKx@seznam.cz>
To: "Konference Delphi" <delphi-l@clexpert.cz>
Sent: Thursday, November 14, 2002 6:57 PM
Subject: Zaboha proc ??? - Dynamicke pole a BlockRead ^


Nazdar,
 zaboha nemuzu prijit na to, proc to nefunguje a vyhazuje hlasku
Access Volation. Chci proste nacist cely soubor do pameti do pole,
ktere se prizpusobi velikosti pole. Neni to tim, ze by nestacila
pamet, ten soubor ma 40kB...
Zkousel jsem ruzne jako napriklad FileSize(INF)-1, v BlockRead misto
SizeOf(B1) na FileSize(INF), a jiné, ale stejný výsledek. Když jsem
B1 přetypoval na pevné pole, tak to jede. Mam D6.

Var B1:Array of Char;
    INF:File Of Char;
    I:LongInt;
Begin
 AssignFile(INF,'C:\E1.EXE');
 {$I-}
 Reset(INF);
 {$I+}
 If IOResult<>0 Then
  Application.MessageBox(PChar('Error1'),PChar(''))
 Else Begin
  SetLength(B1,FileSize(INF));
  BlockRead(INF,B1,SizeOf(B1),I);
  CloseFile(INF);
 End;
...
End;

______________________________________________________________________
Reklama:
Poctenicko pro kazdy den: http://www.novinky.cz

Odpovedá: Petr Langer

14. 11. 2002 21:00

Nechce se mi to zkouset, ale nepomuze napsat BlockRead:
BlockRead(INF,B1[0],SizeOf(B1),I);
pripadne jiny index ?
Jeste mne napada, zkus si udelat promenou myChar : PChar a myChar :=
@B1; a pouzit

BlockRead(INF,myChar,SizeOf(B1),I);

mozna to nepomuze...

pl

----- Original Message -----
From: "David Kraina" <DKx@seznam.cz>
To: "Konference Delphi" <delphi-l@clexpert.cz>
Sent: Thursday, November 14, 2002 6:57 PM
Subject: Zaboha proc ??? - Dynamicke pole a BlockRead ^


Nazdar,
 zaboha nemuzu prijit na to, proc to nefunguje a vyhazuje hlasku
Access Volation. Chci proste nacist cely soubor do pameti do pole,
ktere se prizpusobi velikosti pole. Neni to tim, ze by nestacila
pamet, ten soubor ma 40kB...
Zkousel jsem ruzne jako napriklad FileSize(INF)-1, v BlockRead misto
SizeOf(B1) na FileSize(INF), a jiné, ale stejný výsledek. Když jsem
B1 přetypoval na pevné pole, tak to jede. Mam D6.

Var B1:Array of Char;
    INF:File Of Char;
    I:LongInt;
Begin
 AssignFile(INF,'C:\E1.EXE');
 {$I-}
 Reset(INF);
 {$I+}
 If IOResult<>0 Then
  Application.MessageBox(PChar('Error1'),PChar(''))
 Else Begin
  SetLength(B1,FileSize(INF));
  BlockRead(INF,B1,SizeOf(B1),I);
  CloseFile(INF);
 End;
...
End;

______________________________________________________________________
Reklama:
Poctenicko pro kazdy den: http://www.novinky.cz


Odpovedá: Dalibor Toman

14. 11. 2002 21:20

> zaboha nemuzu prijit na to, proc to nefunguje a vyhazuje hlasku
>Access Volation. Chci proste nacist cely soubor do pameti do pole,
>ktere se prizpusobi velikosti pole. Neni to tim, ze by nestacila
>pamet, ten soubor ma 40kB...
>Zkousel jsem ruzne jako napriklad FileSize(INF)-1, v BlockRead misto
>SizeOf(B1) na FileSize(INF), a jiné, ale stejný výsledek. Když jsem
>B1 přetypoval na pevné pole, tak to jede. Mam D6.

zkusil bych dve veci :

1)
misto
  Reset(INF);

bych pouzil
 Reset(INF,1);

nevim jak ted v Delphi - ale byvaly s tim problemy v DOSu (defaut record
size neni 1 ale 128 = cili ve skutecnosti se nacte N x 128 bytu volanim
BlockRead)

2)
misto
  BlockRead(INF,B1,SizeOf(B1),I);

bych pouzil:
  BlockRead(INF,B1[Low(B1)],SizeOf(B1),I);

ta prvni varianta prepisuje hodnotu pointeru na pole ne vlastni pole
(podobny pripad jako s promennou typu string)

D. Toman

Odpovedá: Ján Harman

14. 11. 2002 22:49

pomuze urcite
Reset (INF, 1);
BlockRead(INF, B1, SizeOf(B1), I);
// kvuli defaultnemu bloku, taky by to slo opacne misto 1 dat Reset(INF,
SizeOF(B1)); a misto SizeOf.. dat 1.


> > zaboha nemuzu prijit na to, proc to nefunguje a vyhazuje hlasku
> >Access Volation. Chci proste nacist cely soubor do pameti do pole,
> >ktere se prizpusobi velikosti pole. Neni to tim, ze by nestacila
> >pamet, ten soubor ma 40kB...
> >Zkousel jsem ruzne jako napriklad FileSize(INF)-1, v BlockRead misto
> >SizeOf(B1) na FileSize(INF), a jiné, ale stejný výsledek. Když jsem
> >B1 přetypoval na pevné pole, tak to jede. Mam D6.
>
> zkusil bych dve veci :
>
> 1)
> misto
> Reset(INF);
>
> bych pouzil
> Reset(INF,1);
>
> nevim jak ted v Delphi - ale byvaly s tim problemy v DOSu (defaut record
> size neni 1 ale 128 = cili ve skutecnosti se nacte N x 128 bytu volanim
> BlockRead)
>
> 2)
> misto
> BlockRead(INF,B1,SizeOf(B1),I);
>
> bych pouzil:
> BlockRead(INF,B1[Low(B1)],SizeOf(B1),I);
>
> ta prvni varianta prepisuje hodnotu pointeru na pole ne vlastni pole
> (podobny pripad jako s promennou typu string)
>
> D. Toman
>
>
>

Odpovedá: Petr Vones

14. 11. 2002 23:57

From: "David Kraina" <DKx@seznam.cz>
> Tak to sice mozna jo, ale neni to resenim, protoze je to strasne pomale.
> Testovaci soubor mel sice 40kB, ale musi to fungovat i pro 40MB a nez to po
> tom jednom znaku donacita, u pocitace usnu.

Jiste, alokovat pamet a do ni pak nacitat soubor je znacne neefektivni zpusob,
protoze ten soubor vlastne (v nejhorsim pripade) cely kopirujes do page filu.
Prave od toho existuje mechanismus mapovani souboru do pameti. Blize v MSDN.

Muzes pouzit tridu TJclFileMapping nebo zjednodusenou TJclFileMappingStream z
JCL se kterou pak pracujes jako s readonly memory streamem.

Petr Vones